//
// Created by ChenJi on 2021/1/8.
//

#include <rtc_extern.h>
#include "TastekE16.h"
#include "usart_extern.h"
#include "lcd_extern.h"
#include "data_center.h"

extern UART_HandleTypeDef huart1;
uint8_t t_isConnected = 0;  //the state to express is it connecting to the GPRS NET;
uint8_t t_isreading = 0;    //the state to express is it reading the pocket
uint8_t t_len = 0;          //the amount to count how many char have been received and express the final length when completed to receive the pocket;
uint8_t t_buffer[256] = {0};  //the buffer area of data.
uint8_t pocket_executeSuccess[4] = {0xEE, 0xFA, 0x00, 0xFE};
uint8_t pocket_time_request[4] = {0xEE, 0x0A, 0x00, 0xFE};
uint8_t pocket_verify[7] = {0xEE, 0xA0, 0x00, 0x00, 0x00, 0x00, 0xFE};
uint8_t time_synced = 0;
uint32_t time_out = 0;
const uint32_t time_limit = 2000;
uint8_t time_out_flag;
const uint8_t CONFIG_DEVICE_ID[4] = "C723";

uint8_t tas_time_not_synced() {
    if (time_out_flag && time_out >= time_limit)
        time_synced = 2;
    return time_synced;
}

void kernal_net_time_out_tick_1ms() {
    time_out++;
}


void onUART3Receive(uint8_t data) {
    if (!t_isConnected) {
        return;
    }
    if (data == 0xEE &&
        !t_isreading) {  //start receiving data receiving the staring char 0xEE and it is not contains in a pocket.
        t_buffer[0] = data;
        t_isreading = 1;
        t_len++;
        return;
    }
    if (t_isreading) {
        t_buffer[t_len] = data;
        t_len++;  //fill the data to the buffer area
    }
    if (t_len == 254) {
        t_len = 0;
        t_isreading = 0;//drop pocket if it is too long to handle
    }
    if (data == 0xFE) {//end to read the pocket until receiving the ending char 0xFA
        t_isreading = 0;
        onRemoteCommandReceived();//handle the pocket
        t_len = 0;
    }
}

void Tas_init() {
    if (HAL_GPIO_ReadPin(GPIOB, GPIO_PIN_0)) {
        t_isConnected = 1;
    }
    uint8_t i = 2;
    pocket_verify[i++] = CONFIG_DEVICE_ID[0];
    pocket_verify[i++] = CONFIG_DEVICE_ID[1];
    pocket_verify[i++] = CONFIG_DEVICE_ID[2];
    pocket_verify[i++] = CONFIG_DEVICE_ID[3];

    if (isConnected())
        onConnected();
    else
        onDisconnected();
}

void onRemoteCommandReceived() {
    debug_UART1(t_buffer, t_len);
    if (t_buffer[2] == 0x1A) {//set year;
        setYear(t_buffer[3]);
        return;
    }

    if (t_buffer[2] == 0x1B) {
        setMonth(t_buffer[3]);
        return;
    }

    if (t_buffer[2] == 0x1C) {
        setDay(t_buffer[3]);
        return;
    }

    if (t_buffer[2] == 0x1D) {
        setHour(t_buffer[3]);
        return;
    }

    if (t_buffer[2] == 0x1E) {
        setMinute(t_buffer[3]);
        return;
    }

    if (t_buffer[2] == 0x1F) {
        setSecond(t_buffer[3]);
        return;
    }

    if (t_buffer[2] == 0x10) {
        syncTime(t_buffer[3], t_buffer[4], t_buffer[5], t_buffer[6], t_buffer[7], t_buffer[8] + 1);
        if (time_out_flag) {
            time_synced = 1;
            time_out_flag = 0;
            time_out = 0;
        }
        sendRemoteCommand(pocket_executeSuccess, 4);
    }
    if (t_buffer[2] == 0x11) {
        if (t_buffer[3])
            onServerVerifyDone();
        else
            onServerVerifyFailed();
    }
    if (t_buffer[2] == 0x12) {
        setStartTime(t_buffer[3], t_buffer[4], t_buffer[5]);
        setEndTime(t_buffer[6], t_buffer[7], t_buffer[8]);
        if (t_buffer[9]) {
            enableAutoSet();
        } else {
            disableAutoSet();
        }
    }
}

uint8_t isConnected() {
    return t_isConnected;
}

uint8_t sendRemoteCommand(uint8_t *data, uint16_t len) {
    if (!t_isConnected)return -1;
    sendData_DMA(data, &huart3, len);
    return 0;
}

void reuqest_time() {
    time_out_flag = 1;
    time_out = 0;
    sendRemoteCommand(pocket_time_request, 4);
}

void onGPIOSwap_0_B(GPIO_PinState state) {
    if (state == GPIO_PIN_SET) {
        t_isConnected = 1;
        setNETStateICON(1);
        onConnected();
    } else {
        t_isConnected = 0;
        setNETStateICON(0);
        onDisconnected();
    }
}

void sendVerifyPocket() {
    sendRemoteCommand(pocket_verify, 7);
}

void verifyTimeSynced() {
    if (!time_synced)sendVerifyPocket();
}